package repository

import (
	"boy-go/modules/system/aspect"
	"boy-go/modules/system/model"
	"boy-go/modules/system/vo"
	"boy-go/pkg/db"
	"boy-go/pkg/request"
	"fmt"
	"gorm.io/gorm"
)

type SysRoleRepository struct {
	DB *gorm.DB
}

var (
	_selectRoleVoLeftJoin = "left join sys_user_role ur on ur.role_id = r.role_id " +
		"left join sys_user u on u.user_id = ur.user_id " +
		"left join sys_dept d on u.dept_id = d.dept_id "
	_selectRoleVo      = "select distinct r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.menu_check_strictly, r.dept_check_strictly, r.status, r.del_flag, r.create_time, r.remark from sys_role r " + _selectRoleVoLeftJoin
	_selectCountRoleVo = "select count(0) from sys_role r " + _selectRoleVoLeftJoin
)

func NewSysRoleRepository() *SysRoleRepository {
	return &SysRoleRepository{
		DB: db.GetMasterDB(),
	}
}
func (r *SysRoleRepository) GetById(roleId int64) (*model.SysRole, error) {
	db := r.DB
	m := &model.SysRole{}
	err := db.Model(&model.SysRole{}).Where("role_id = ?", roleId).First(m).Error
	if err != nil {
		return nil, err
	}
	return m, nil
}
func (r *SysRoleRepository) GetByRoleName(roleName string) (*model.SysRole, error) {
	db := r.DB
	m := &model.SysRole{}
	err := db.Model(&model.SysRole{}).Where("role_name = ?", roleName).Where("del_flag = ?", "0").First(m).Error
	if err != nil {
		return nil, err
	}
	return m, nil
}
func (r *SysRoleRepository) GetByRoleKey(roleName string) (*model.SysRole, error) {
	db := r.DB
	m := &model.SysRole{}
	err := db.Model(&model.SysRole{}).Where("role_key = ?", roleName).Where("del_flag = ?", "0").First(m).Error
	if err != nil {
		return nil, err
	}
	return m, nil
}
func (r *SysRoleRepository) List(query *vo.QuerySysRoleReq, page *request.PageRequest) ([]*model.SysRole, int64, error) {
	tx := r.DB
	list := make([]*model.SysRole, 0)
	whereSQL := " where r.del_flag = '0'"
	if query != nil {
		if query.RoleId != nil {
			whereSQL += " and r.role_id = " + fmt.Sprintf("%d", *query.RoleId)
		}
		if query.RoleName != nil {
			whereSQL += fmt.Sprintf(" and r.role_name like '%s'", "%"+*query.RoleName+"%")
		}
		if query.Status != nil {
			whereSQL += " and r.status = " + fmt.Sprintf("%s", *query.Status)
		}
		if query.RoleKey != nil {
			whereSQL += fmt.Sprintf(" and r.role_key like '%s'", "%"+*query.RoleKey+"%")
		}
		if query.Params != nil {
			val, have := query.Params["beginTime"]
			if have {
				beginTime := val.(string)
				whereSQL += (" and date_format(r.create_time,'%Y%m%d') >= date_format('" + beginTime + "','%Y%m%d')")
			}
			val, have = query.Params["endTime"]
			if have {
				endTime := val.(string)
				whereSQL += (" and date_format(r.create_time,'%Y%m%d') <= date_format('" + endTime + "','%Y%m%d')")
			}
		}
	}
	if page != nil {
		var total int64
		sql := _selectCountRoleVo + whereSQL
		if err := tx.Raw(sql).Find(&total).Error; err != nil {
			return nil, 0, err
		}
		if total > 0 {
			sql = _selectRoleVo + whereSQL
			aspect.HandleDataScope(&sql, "d", "")
			db.BuildPageAndOrderSQL(&sql, page, "r.role_sort")
			err := tx.Raw(sql).Find(&list).Error
			if err != nil {
				return nil, total, err
			}
		}
		return list, total, nil
	} else {
		sql := _selectRoleVo + whereSQL
		aspect.HandleDataScope(&sql, "d", "")
		err := tx.Raw(sql).Find(&list).Error
		if err != nil {
			return nil, 0, err
		}
	}
	return list, int64(len(list)), nil
}

// Save 添加
func (r *SysRoleRepository) Save(m *model.SysRole) error {
	return r.DB.Model(&model.SysRole{}).Create(m).Error
}

// Update 更新
func (r *SysRoleRepository) Update(m *model.SysRole) error {
	return r.DB.Model(&model.SysRole{}).Where("role_id = ?", m.RoleId).Updates(m).Error
}

// Delete 删除
func (r *SysRoleRepository) Delete(roleId int64) error {
	return r.DB.Model(&model.SysRole{}).Where("role_id = ?", roleId).Delete(&model.SysRole{}).Error
}

// DeleteBatch 批量删除
func (r *SysRoleRepository) DeleteBatch(ids []interface{}) error {
	db := r.DB
	db = db.Where("(role_id)", ids)
	return db.Delete(&model.SysRole{}).Error
}

func (r *SysRoleRepository) SelectRolePermissionByUserId(userId int64) []model.SysRole {
	roles := make([]model.SysRole, 0)
	sql := _selectRoleVo + "WHERE r.del_flag = '0' and ur.user_id = " + fmt.Sprintf("%d", userId)
	err := r.DB.Raw(sql).Find(&roles).Error
	if err != nil {
		return nil
	}
	return roles
}
func (r *SysRoleRepository) SelectRoleByUserId(userId int64) ([]*model.SysRole, error) {
	list := make([]*model.SysRole, 0)
	sql := "select r.* from sys_user_role ur left join sys_role r on r.role_id = ur.role_id where ur.user_id = " + fmt.Sprintf("%d", userId)
	err := r.DB.Raw(sql).Find(&list).Error
	return list, err
}
